package com.androsz.andslr.app;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.mtp.MtpDevice;
import android.mtp.MtpObjectInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.os.Build.VERSION;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ProgressBar;

import com.androsz.andslr.R;
import com.androsz.util.IntentUtil;

public class PreImportFragment extends AnalyticFragment {

	public static final String SCANNED_FILES = "scannedFiles";

	@Override
	public void onDestroy() {
		ptpDevice.close();
		super.onDestroy();
	}

	// searches for a PTP interface on the given USB device
	private static boolean hasPtpInterface(UsbDevice device) {
		int count = device.getInterfaceCount();
		for (int i = 0; i < count; i++) {
			UsbInterface intf = device.getInterface(i);
			if (intf.getInterfaceClass() == 6
					&& intf.getInterfaceSubclass() == 1
					&& intf.getInterfaceProtocol() == 1) {
				return true;
			}
		}
		return false;
	}

	private MtpDevice claimPtpDevice(UsbDevice device) {

		UsbManager usbManager = (UsbManager) getActivity().getSystemService(
				Context.USB_SERVICE);
		if (device != null) {
			if (hasPtpInterface(device)) {
				UsbDeviceConnection connection = usbManager.openDevice(device);
				if (connection != null) {
					MtpDevice ptpDevice = new MtpDevice(device);
					ptpDevice.open(connection);
					return ptpDevice;
				} else {
					trackEvent(String.format(
							"addPtpDevice null connection: %s",
							device.getProductId()), 0);
				}
			} else {
				trackEvent(String.format("addPtpDevice !hasPtpInterface: %s",
						device.getProductId()), 0);
			}
		} else {
			trackEvent("addPtpDevice null device", 0);
		}
		return null;
	}

	private MtpDevice ptpDevice;
	private ArrayList<Integer> scannedFiles;

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		UsbDevice usbDevice = (UsbDevice) getArguments().getParcelable(
				UsbManager.EXTRA_DEVICE);

		ptpDevice = claimPtpDevice(usbDevice);

		final View v = getView();

		((TextView) v.findViewById(R.id.textview_scanning_device))
				.setText(getString(R.string.scanning_device, ptpDevice
						.getDeviceInfo().getModel()));

		AsyncTask<Void, Integer, Void> scanTask = new AsyncTask<Void, Integer, Void>() {

			@Override
			protected void onProgressUpdate(Integer... values) {
				super.onProgressUpdate(values);
				foundImages.setText(getString(R.string.found_x_images,
						values[0]));
			}

			private ArrayList<Integer> scannedFiles;
			TextView foundImages;

			@Override
			protected void onPostExecute(Void result) {
				if (!scannedFiles.isEmpty()) {
					updateUIOnSuccess(v, scannedFiles.size());
					PreImportFragment.this.scannedFiles = new ArrayList<Integer>(
							scannedFiles);
				}
				super.onPostExecute(result);
			}

			@Override
			protected void onPreExecute() {
				scannedFiles = new ArrayList<Integer>();
				foundImages = ((TextView) getView().findViewById(
						R.id.textview_found_images));
				super.onPreExecute();
			}

			@Override
			protected Void doInBackground(Void... params) {
				for (int id : ptpDevice.getStorageIds()) {
					int[] handles = ptpDevice.getObjectHandles(id, 0, 0);
					for (int handle : handles) {
						MtpObjectInfo mtpoi = ptpDevice.getObjectInfo(handle);
						if (mtpoi.getImagePixHeight() != 0) {
							scannedFiles.add(mtpoi.getObjectHandle());
							publishProgress(scannedFiles.size());
						}
					}
				}
				return null;
			}
		};

		if (savedInstanceState == null) {
			scanTask.execute();
		} else {
			scannedFiles = savedInstanceState
					.getIntegerArrayList(SCANNED_FILES);

			if (scannedFiles == null) {
				scanTask.execute();
			} else if (!scannedFiles.isEmpty()) {
				updateUIOnSuccess(v, scannedFiles.size());
			}
		}
	}

	private void updateUIOnSuccess(final View v, final int imagesCount) {
		Button buttonImport = (Button) v.findViewById(R.id.button_import);
		buttonImport.setEnabled(true);
		buttonImport.setText(getString(R.string.import_enabled, imagesCount));
		((RelativeLayout) v.findViewById(R.id.relativelayout_scanning))
				.setVisibility(View.GONE);
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putIntegerArrayList(SCANNED_FILES, scannedFiles);
	}

	@Override
	public void onPause() {
		super.onPause();
		getActivity().unbindService(serviceConnection);
	}

	@Override
	public void onResume() {
		super.onResume();
		Activity a = getActivity();
		a.bindService(new Intent(a, PreImportService.class), serviceConnection,
				Service.BIND_AUTO_CREATE);
	}

	private ServiceConnection serviceConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder iservice) {
		}

		public void onServiceDisconnected(ComponentName className) {
		}
	};

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		View v = inflater.inflate(R.layout.fragment_pre_import, container,
				false);

		Button buttonImportDirectory = (Button) v
				.findViewById(R.id.button_import_directory);

		buttonImportDirectory.setText(Environment
				.getExternalStoragePublicDirectory(
						Environment.DIRECTORY_PICTURES).toString());

		return v;

	}

	private final static int PICK_DIRECTORY_REQUEST_CODE = 0xBEEF;

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode != Activity.RESULT_OK || data == null)
			return;
		switch (requestCode) {
		case PICK_DIRECTORY_REQUEST_CODE:
			Uri dataUri = data.getData();
			((Button) getActivity().findViewById(R.id.button_import_directory))
					.setText(dataUri.getPath());
			break;
		}

		super.onActivityResult(requestCode, resultCode, data);
	}

	@Override
	public void onClick(View v) {
		if (v == null)
			return;

		switch (v.getId()) {
		case R.id.button_import:
			FragmentTransaction ft = getFragmentManager().beginTransaction();
			Fragment f = new DuringImportFragment();
			Bundle b = new Bundle();
			b.putIntegerArrayList(SCANNED_FILES, scannedFiles);
			f.setArguments(b);
			ft.replace(R.id.relativelayout_import, f);

			ft.setCustomAnimations(android.R.animator.fade_in,
					android.R.animator.fade_out);
			ft.commit();
			break;

		case R.id.button_import_directory:
			Button buttonImportDirectory = (Button) getView().findViewById(
					R.id.button_import_directory);
			IntentUtil.OIPickDirectory(this, PICK_DIRECTORY_REQUEST_CODE,
					buttonImportDirectory.getText().toString());
			break;

		case R.id.button_import_cancel:
			getActivity().finish();
			break;

		}
	}
}
